#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include "rename.h"

#include <QtWidgets>
#include <QStandardPaths>

#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    thread  = new MyThread();
    
    this->init_widget();
    this->init_connect();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init_widget()
{
    ui->tabWidget->setTabText(0, "命名");
    ui->tabWidget->setTabText(1, "图片");
    
    QStringList header;
    header << "原文件名" << "预览" << "结果";
    ui->tableWidget->setRowCount(18);   //设置行数为18
    ui->tableWidget->setColumnCount(3); //设置列数为3
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
    
    QHeaderView *headerView = ui->tableWidget->horizontalHeader();
    headerView->setSectionsMovable(false);//去除表头的移动
    headerView->setDefaultSectionSize(100);
    
    QHeaderView *verticalHeader  = ui->tableWidget->verticalHeader();
    verticalHeader->setVisible(false);
    verticalHeader->setDefaultSectionSize(15);
    
    image_button_group  = new QButtonGroup;
    image_button_group->addButton(ui->fillRadioButton,      1);
    image_button_group->addButton(ui->scaledRadioButton,    2);
    image_button_group->addButton(ui->fitWidthRadioButton,  3);
    image_button_group->addButton(ui->fitHeightRadioButton, 4);
    image_button_group->button(1)->setChecked(true);
}

void MainWindow::init_connect()
{
    connect(ui->addFileButton,      SIGNAL(clicked()),              this, SLOT(add_file()));
    connect(ui->clearFileButton,    SIGNAL(clicked()),              this, SLOT(clear_file()));
    connect(ui->startPushButton,    SIGNAL(clicked()),              this, SLOT(start()));
    connect(ui->closePushButton,    SIGNAL(clicked()),              this, SLOT(close()));
    
    connect(thread,                 SIGNAL(send_status(int,bool)),  this, SLOT(update_status(int, bool)));
    
    connect(ui->oldStrLineEdit,     SIGNAL(textChanged(QString)),   this, SLOT(rename()));
    connect(ui->newStrLineEdit,     SIGNAL(textChanged(QString)),   this, SLOT(rename()));
    connect(ui->beforeStrLineEdit,  SIGNAL(textChanged(QString)),   this, SLOT(rename()));
    connect(ui->afterStrLineEdit,   SIGNAL(textChanged(QString)),   this, SLOT(rename()));
    connect(ui->addCheckBox,        SIGNAL(clicked(bool)),          this, SLOT(rename()));
    connect(ui->addSpinBox,         SIGNAL(valueChanged(int)),      this, SLOT(rename()));
    connect(ui->addStrLineEdit,     SIGNAL(textChanged(QString)),   this, SLOT(rename()));
    connect(ui->delStrLineEdit,     SIGNAL(textChanged(QString)),   this, SLOT(rename()));
    connect(ui->delCheckBox,        SIGNAL(clicked(bool)),          this, SLOT(rename()));
    connect(ui->delSpinBox,         SIGNAL(valueChanged(int)),      this, SLOT(rename()));
    connect(ui->delNumSpinBox,      SIGNAL(valueChanged(int)),      this, SLOT(rename()));
    
    connect(ui->txtLineEdit,        SIGNAL(textChanged(QString)),   this, SLOT(load_txt_file()));
    connect(ui->txtFileButton,      SIGNAL(clicked(bool)),          this, SLOT(txt_file()));
    connect(ui->createFileButton,   SIGNAL(clicked(bool)),          this, SLOT(create_filename()));
    
    connect(ui->imageDirButton,     SIGNAL(clicked(bool)),          this, SLOT(image_dir()));
    
    connect(ui->addCheckBox,        SIGNAL(clicked(bool)),          ui->addSpinBox,     SLOT(setEnabled(bool)));
    connect(ui->addCheckBox,        SIGNAL(clicked(bool)),          ui->addStrLineEdit, SLOT(setEnabled(bool)));
    connect(ui->delCheckBox,        SIGNAL(clicked(bool)),          ui->delSpinBox,     SLOT(setEnabled(bool)));
    connect(ui->delCheckBox,        SIGNAL(clicked(bool)),          ui->delNumSpinBox,  SLOT(setEnabled(bool)));
    
    connect(ui->imageCheckBox,      SIGNAL(clicked(bool)),          ui->imageFrame,             SLOT(setEnabled(bool)));
    connect(ui->imageCheckBox,      SIGNAL(clicked(bool)),          ui->imageQualityComboBox,   SLOT(setEnabled(bool)));
    connect(ui->imageTypeCheckBox,  SIGNAL(clicked(bool)),          ui->imageTypeComboBox,      SLOT(setEnabled(bool)));
}

//slots
//添加文件
void MainWindow::add_file() 
{
    QStringList list    = QFileDialog::getOpenFileNames(this, QString("选择文件"),  QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), "所有文件(*);;图片文件(*.jpg *.png *.jpeg *.bmp *.gif)");
    filepath_list << list;
    int length  = filepath_list.count();
    int rows    = length > 18 ? length : 18;
    ui->tableWidget->setRowCount(rows);
    for(int i = 0; i < length; ++i) {
        QString filepath = filepath_list.at(i);
        QFileInfo fi(filepath);
        QString filename = fi.fileName();
        ui->tableWidget->setItem(i, 0, new QTableWidgetItem(filename));
    }
    this->rename();
}

void MainWindow::clear_file()
{   
    ui->tableWidget->clearContents();
    ui->tableWidget->setRowCount(18);
    filepath_list.clear();
}

void MainWindow::rename ()
{
    QString old_str     = ui->oldStrLineEdit->text();
    QString new_str     = ui->newStrLineEdit->text();
    QString before_str  = ui->beforeStrLineEdit->text();
    QString after_str   = ui->afterStrLineEdit->text();
    
    int add_check       = ui->addCheckBox->checkState();    // Qt::Unchecked 0 Qt::PartiallyChecked 1 Qt::Checked 2    
    int add_postion     = ui->addSpinBox->value();
    QString add_str     = ui->addStrLineEdit->text();
    
    QString del_str     = ui->delStrLineEdit->text();    
    int del_check       = ui->delCheckBox->checkState();
    int del_postion     = ui->delSpinBox->value();
    int del_num         = ui->delNumSpinBox->value();
    
    int length  = filepath_list.count();
    filesave_list.clear();
    for(int i = 0; i < length; ++i) {
        QString     filepath = filepath_list.at(i);
        QFileInfo   fi(filepath);
        QString     filename = fi.fileName();
        Rename      name(filename);
        name.replace(old_str, new_str);
        name.insert(0, before_str);
        name.after(after_str);
        if(Qt::Checked == add_check) {
            name.insert(add_postion-1, add_str);
        }
        name.remove(del_str);
        if(Qt::Checked == del_check) {
            name.remove(del_postion-1, del_num);
        }
        if(false == filename_hash.isEmpty()) {
            QString after_str = filename_hash.value(name.getbasename());
            if(!after_str.isEmpty()){
                name.swap(after_str);
            }
        }
        ui->tableWidget->setItem(i, 1, new QTableWidgetItem(name.filename()));           
        filesave_list << fi.absolutePath() + '/' + name.filename();
    }
}

void MainWindow::txt_file()
{
    QString filename    = QFileDialog::getOpenFileName(this, QString("选择文本文件"),  QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), "文本文件(*.txt)");
    ui->txtLineEdit->setText(filename);
}

void MainWindow::load_txt_file()
{
    filename_hash.clear();
    
    QString filename    = ui->txtLineEdit->text();
    if(filename.isEmpty()) return;
    
    QFile *file = new QFile(filename);
    if(!file->open(QIODevice::ReadOnly)) return;
    if(!file->size()) return;
    
    QTextStream input(file);
    QString line;
    
    while(!input.atEnd()){
        line = input.readLine();
        QStringList row = line.split(QRegExp("\\s+"));
        if(row.count() < 2) break;
        if(row.first().isEmpty()) break;
        filename_hash.insert(row.at(0), row.at(1));
    }
    file->close();
    this->rename();
}

void MainWindow::image_dir()
{
    QString dirname = QFileDialog::getExistingDirectory(this, QString("选择保存文件夹"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), QFileDialog::ShowDirsOnly);
    ui->imageDirLineEdit->setText(dirname);
}

void MainWindow::create_filename()
{
    if(filepath_list.isEmpty()) return;
    QString filename    =  QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + '/' + "图片名列表.txt";
    QFile file(filename);
    file.open(QIODevice::Text | QIODevice::WriteOnly);//增加text属性才能换行
    QTextStream out(&file);
    
    int length  = filepath_list.count();
    for(int i = 0; i < length; ++i) {
        QString     filepath = filepath_list.at(i);
        QFileInfo   fi(filepath);
        QString     filename = fi.fileName();
        Rename      rename(filename);
        out << rename.getbasename() << endl;
    }
    file.close();
    this->message("成功生成文件名列表到桌面");
}

void MainWindow::start()
{
    if(filepath_list.isEmpty()) return;
    
    setCursor(Qt::WaitCursor);
    success_num = 0;
    fail_num    = 0;
    this->message("开始处理...");
    if(Qt::Checked == ui->imageCheckBox->checkState()) {
        QString image_dir_str   = ui->imageDirLineEdit->text();
        QString image_dir;
        if(false == image_dir_str.isEmpty()) {
            image_dir   = image_dir_str;
        } else {
            QString output_str = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + '/' + "output";
            QDir dir;
            if(false == dir.exists(output_str)) {
                dir.mkdir(output_str);
            }
            image_dir = output_str;
        }
        
        filesave_list.clear();
        int length      = filepath_list.length();
        QString suffix  = ui->imageTypeComboBox->currentText();
        for(int i = 0; i < length; i++){
            QString filename = ui->tableWidget->item(i, 1)->text();
            Rename name(filename);
            if(Qt::Checked == ui->imageTypeCheckBox->checkState()) {
                name.swap_suffix(suffix);
            }
            filesave_list << image_dir + '/' + name.filename();
        }
        
        thread->set_rename(filepath_list, filesave_list);
        int width   = ui->imageWidthLineEdit->text().toInt();
        int height  = ui->imageHeightLineEdit->text().toInt();
        int quality = ui->imageQualityComboBox->currentText().toInt();
        int type    = image_button_group->checkedId();
        thread->set_image(width, height, quality, Reimage::Type(type));
    }    

    thread->set_rename(filepath_list, filesave_list);
    thread->start();
}

void MainWindow::update_status(int row, bool status)
{
    QString row_str = status ? "成功" : "失败";
    if(status) {
        row_str = "成功"; 
        success_num++;
    } else {
        row_str = "失败";
        fail_num++;
    }
    ui->tableWidget->setItem(row, 2, new QTableWidgetItem(row_str));
    int length  = filepath_list.length();
    QString message;
    if(row + 1 < length) {
        message = "正在处理... " + QString::number(row+1) + '/' + QString::number(length);
    } else {
        setCursor(Qt::ArrowCursor);
        message = "处理结束";
    }
    message = message
            + " 成功：" + QString::number(success_num)
            + " 失败：" + QString::number(fail_num);
    this->message(message);
}

void MainWindow::message(QString str)
{
    ui->messageLabel->setText(str);
}
